#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//下面都是本地文件
#include "../head/default.h"         //define 宏定义及static变量                                      
#include "../head/log.h"         //define 宏定义及static变量                                      
void f_logging(enum LogLevel level, const char *fmt, ...);
int f_find_char (char str[], char *value);
int f_my_split(char buf[], const char *split, char *res[]);
int f_del_char(char str[], char res[], char c);


int f_my_check_comm(char *bl_comm[], int max_index, char comm[]) {
    //处理client输入的命令是否在程序定义的黑名单, client端调用
    int mark = 0;
    char log_info[VAR_MAX_LEN];
    for (int i = 0; i < max_index; i++) {
        if (strstr(bl_comm[i], comm)) {
            sprintf(log_info, "GLOBAL --> 暂不支持 '%s' 的操作!", comm);
            f_logging(ERROR, log_info);
            mark = -1;
        }
    }
    return mark;
}

int f_default_check_comm(char *bl_comm[], int max_index, char comm[]) {
    //处理程序定义的黑名单, client端调用
    int mark = 0;
    if (strstr(comm, "&&")) {
        f_logging(ERROR, "GLOBAL --> 暂不支持带有 '&&' 的操作!");
        mark = -1;
    } else if (strstr(comm, ";")) {
        f_logging(ERROR, "GLOBAL --> 暂不支持带有 ';' 的操作!");
        mark = -1;
    } else if (strstr(comm, " * ")) {
        f_logging(ERROR, "GLOBAL --> 暂不支持带有 ' * ' 的操作!");
        mark = -1;
    } else {
        mark = f_my_check_comm(bl_comm, max_index, comm);
    }
    return mark;
}

int f_check_comm_on_server(char *argv[], char comm[]) {
    //server端调用
    char *res[VAR_TMP_MAX_LEN];         //用户定义的命令黑名单, 通过处理保存到这个字符串数组(按逗号分割)
    char *res_tmp[VAR_TMP_MAX_LEN];     //client传过来的命令, 通过处理保存在这个字符串数组(按管道符|分割)
    char *res_tmp2[VAR_TMP_MAX_LEN];    //res_tmp数组是经过管道符处理以后, 然后将每个数组元素再按照空格处理保存到res_tmp2数组, 然后取第一个元素就是命令
    char *split = ",";
    int mark = 0;
    int max_index = f_find_char(argv[9], split) + 1;

    for(int i = 0; i < max_index; i++) { //定义一个临时变量, 用来接收读取配置文件的字符串
        res[i] = (char *)malloc(VAR_TMP_MAX_LEN);
    }
    f_my_split(argv[9], split, res);

    //处理用户输入进来的命令, 先按管道符分割, 然后按空格分割, 取第一个
    split = "|";
    int tmp_index = f_find_char(comm, split) + 1;
    for(int i = 0; i < tmp_index; i++) { //定义一个临时变量, 用来接收读取配置文件的字符串
        res_tmp[i] = (char *)malloc(VAR_TMP_MAX_LEN);
    }
    f_my_split(comm, split, res_tmp);

    split = " ";

    for(int i = 0; i < tmp_index; i++) {

        int tmp2_index = f_find_char(res_tmp[i], split) + 1;
        for(int i = 0; i < tmp2_index; i++) { //定义一个临时变量, 用来接收读取配置文件的字符串
            res_tmp2[i] = (char *)malloc(VAR_TMP_MAX_LEN);
        }

        f_my_split(res_tmp[i], split, res_tmp2);

        char tmp[VAR_TMP_MAX_LEN];
        for (int j = 0; j < tmp2_index; j++) {
            if (strcmp(res_tmp2[j], "(") == 0) { //预防通过()fork进程的方式执行命令, 如(echo xxx)这样如果echo是黑名单里面也会识别不了
                continue;
            }
            memset(tmp, 0x00, strlen(tmp));
            f_del_char(res_tmp2[j], tmp, '('); //去掉命令的左括号
            memset(res_tmp2[j], 0x00, strlen(res_tmp2[j]));
            f_del_char (tmp, res_tmp2[j], ')');  //去掉命令的右括号
            int mark_tmp = f_my_check_comm(res, max_index, res_tmp2[j]);
            if (mark_tmp != 0) {
                mark = mark_tmp;
            }
        }

        for(int j = 0; j < tmp2_index; j++) { //定义一个临时变量, 用来接收读取配置文件的字符串
            ; //free(res_tmp2[j]);
        }
    }

    for(int i = 0; i < max_index; i++) { //释放内存
        free(res[i]);
    }

    for(int i = 0; i < tmp_index; i++) { //释放内存
        free(res_tmp[i]);
    }
    return mark;
}
